#include "LFSR.h"


/*Calcule le nouveau bit produit par un LFSR dont le polynôme de rétroaction est P (de degré <= 32),
 * et dont le registre contient actuellement a
 *
 *
 * CETTE FONCTION EST FAUSSE. INUTILE DE LA CORRIGER : ELLE NE SERA PROBABLEMENT PAS UTILISEE.
 * POUR L'INSTANT, JE LA LAISSE QUAND MEME, AU CAS OU.
 *
 *
 */
int retroaction(uint a, uint P)
{
  P = P<<1;
  return uXOR(P & a);
}


uint* LFSR(int L, uint* P, uint* a, int N)
/* Calcule les N premiers bits générés par un LFSR de longueur L et de polynôme de rétroaction P,
 * qui contient initialement les L premiers bits de a.
 */
{
  //Calcul de la taille des tableaux G (les N bits générés), P et a
  int nbG = Ntaille(N);
  int nbP = Ntaille(L+1);
  int nba = Ntaille(L);

  uint* G = malloc(nbG * sizeof(uint)); //La suite générée G sera un tableau de nb uints
  uint* b = Nretourne(a, nba, L); //a est "à l'envers" dans le LFSR : son premier bit est tout à droite du registre.
  uint* c = malloc(nba * sizeof(uint)); //Intermédiaire de calcul pour la rétroaction


  Ngauche(P, nbP); //C'est le deuxième coefficient de P qui correspond à la première case du LFSR

  int i, j;
  for (i = 0; i < N; i++) //Itérations du LFSR
  {
    setBit(G, nbG, i, Nbit(b, nba, L-1)); //On met dans G le bit qui va sortir du LFSR : le bit n°(L-1) de b
    //printf("%d\n", Nbit(b, nba, L-1));
    for (j = L; j < nba * 32; j++) setBit(a, nba, j, 0);
      
    for (j = 0; j < nba; j++) c[j] = P[j] & b[j];

    if (NXOR(c, nba) == 0) //Si le nouveau bit généré à gauche est 0
    {
      Ndroite(b, nba); //On décale b d'un cran vers la droite
      uzero(b, 0); //On place le nouveau bit généré à gauche de b
    }
    else //Si le bit généré est 1
    {
      Ndroite(b, nba); //On décale b d'un cran vers la droite
      uun(b, 0);
    }
  }
  return G;
}



/*
   ________
  |      | |
  ->|1|1|0|0|1|->

  Suite générée théorique : 100110101
  */

/*
int main(int argc, char *argv[])
{


  int L = 34;
  int nbchar = 108263;
  int nbclairconnu_char = 8;
  int nbclairconnu_uint = 8/2;
  uint *P, *a;

//  unsigned int line_buffer[BUFSIZ]; /* BUFSIZ is defined if you include stdio.h *//*
  char *buffer;
    int nbline=0,i=0;
  FILE* monfichier = fopen(argv[1],"rb");
  FILE* output = fopen("output2.pdf","wb");
  /*if(monfichier != NULL){
    buffer = malloc(line_buffer);
    while(fgets(buffer,sizeof(unsigned int)*50000,monfichier)){
        i++;
       fprintf(output2,"%s",buffer);
       printf("%d>%d\n",i,buffer);
       buffer = malloc(line_buffer);
    }
  }
  else
    printf("fichier manquant\n");*//*

    // LECTURE DU FICHIER PDF

    fseek(monfichier, 0L, SEEK_END);
    long s = ftell(monfichier);
    rewind(monfichier);
    buffer = malloc(s);
    if ( buffer != NULL )
    {
      fread(buffer, s, 1, monfichier);
      // we can now close the file
      fclose(monfichier); monfichier = NULL;

        // do something, e.g.

      fwrite(buffer, s, 1, output);
    }
    if (monfichier != NULL) fclose(monfichier);


  /* DEFINITION DU NOMBRE D'ELEMENT A CHIFFRER
  ** longueur en bit/char/uint
  *//*

  nbchar = s; //108263;
  int nbuint = s/2;
  int nbbit = s*8;

  nbclairconnu_char = 8; //%PDF-1.2
  nbclairconnu_uint = nbclairconnu_char/2;
  int nbclairconnu_bits = nbclairconnu_char*8;


  P = malloc(2 * sizeof(uint));
  a = malloc(2 * sizeof(uint));
  Nedit(P, 2, "10011000100000000000000000000000001");
  Nedit(a, 2, "0010010100100111110100101100010110");
/*
  P = malloc(1 * sizeof(uint));
  a = malloc(1 * sizeof(uint));


  Nedit(P, 1, "100110001");
  Nedit(a, 1, "00100101");
*//*

  int longueur = Nstore(&a,buffer);

  printf("P : ");
  Naffiche(P, 1, 32);
  printf("\na : ");
  Naffiche(a, 1, 32);
  printf("\n");


  uint crypte;
  uint* G = LFSR(L, P, a, nbuint);

  printf("G : \n");
  printf("Taille G uint: %d [0-%d]\n",nbuint,nbuint-1);
  Naffiche(G, nbuint, nbbit);
  printf("\n");
/*
  uint crypte;
  uint* G = LFSR(L, P, a, nbbit);

  printf("Suite obtenue  : ");
  Naffiche(G, nbuint , nbuint*32);
  printf("\n");
*//*
  //char txtClair[12] = "%PDF-1.2";
  uint* clair;
  Nstore(&clair, buffer);
  Naffiche(clair, nbuint,nbuint*32);
  printf("\n");

  //uint* chiffre = malloc(nbchar/2 * sizeof(uint));
  uint* chiffre = malloc(s);

/*
  chiffre[0] = clair[0] ^ G[0];
  chiffre[1] = clair[1] ^ G[1];
  chiffre[2] = clair[2] ^ G[2];
  chiffre[3] = clair[3] ^ G[3];*//*

for(i = 0; i < nbuint; i++)
    chiffre[i] = clair[i] ^ G[i];

  //Naffiche(chiffre, s, s*32);
  printf("\n");

  FILE* output3 = fopen("test2.out","wb");
  //fwrite(buffer, sizeof(uint), s*32,output3);
  fwrite(chiffre, s, 1, output3);
  fclose(output3);
  // libere le buffer de lecture
  free(buffer);
  return 0;
}*/


